package com.hsmw.api.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.hsmw.api.config.jwt.CurrentHsmwUserUtils;
import com.hsmw.api.config.jwt.JwtTokenUtils;
import com.hsmw.api.config.jwt.LoginUser;
import com.htn.common.core.util.ErrorCodeUtil;
import com.hsmw.api.exception.ApiException;
import com.htn.common.core.base.DataResponse;
import com.htn.common.core.constant.AccountTypeEnum;
import com.htn.common.core.constant.CommonConstants;
import com.htn.common.core.constant.HtnUserTypeEnum;
import com.htn.common.core.constant.UserTypeEnum;
import com.hsmw.common.context.SecurityConstants;
import com.hsmw.api.utils.CommonUtils;
import com.htn.common.core.utils.StringUtils;
import com.hsmw.domain.*;
import com.hsmw.domain.vo.LoginRequestVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.htn.common.core.constant.CommonConstants.ResponseStatus.SUCCESS;

/**
 * @author shuang.kou
 **/
@Service
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class AuthService {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	private CurrentHsmwUserUtils currentHsmwUserUtils;


	@Autowired
	private HsmwPmUserService hsmwPmUserService;

	@Autowired
	private HsmwConcreteUserService hsmwConcreteUserService;

	@Autowired
	private HsmwDriverUserService hsmwDriverUserService;

	@Autowired
	private HsmwBizUserService hsmwBizUserService;

	@Autowired
	private HsmwHtnUserService hsmwHtnUserService;

	@Autowired
	private HsmwTpspUserService hsmwTpspUserService;

	@Autowired
	private HsmwSaleUserService hsmwSaleUserService;

	@Autowired
	private HsmwItemService hsmwItemService;


	public void deleteTokenFromRedis() {
		stringRedisTemplate.delete(currentHsmwUserUtils.getCurrentUserInfo().getId());
	}

	public DataResponse getToken(LoginRequestVO loginRequest) {
		String ifExistsItem="0";
		HashMap<String, String> dataMap = Maps.newHashMap();
		String type = loginRequest.getType();
		String username = loginRequest.getUsername();
		LoginUser loginUser = new LoginUser();
		if(AccountTypeEnum.BIZ.getValue().equals(type)){
			HsmwBizUser hsmwBizUser = hsmwBizUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwBizUser)){
				return  DataResponse.failure(ErrorCodeUtil.E_220,"该管理员账号不存在！");
			}
			if (loginRequest.getType().equals(CommonConstants.UserRole.BIZ.name()) /*&& !hsmwBizUserService.check(loginRequest.getPassword(), hsmwBizUser.getPassword())*/) {
				throw new ApiException(CommonConstants.ResponseStatus.USERNAME_ORE_PASSWORD_ERROR);
			}
			loginUser.setId(hsmwBizUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(hsmwBizUser.getName());
			loginUser.setEnabled(hsmwBizUser.getEnabled());
		}
		if(AccountTypeEnum.CONCRETE.getValue().equals(type)){
			HsmwConcreteUser hsmwConcreteUser = hsmwConcreteUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwConcreteUser)){
				return  DataResponse.failure(ErrorCodeUtil.E_220,"该搅拌站账号不存在！");
			}
			loginUser.setId(hsmwConcreteUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(hsmwConcreteUser.getName());
			loginUser.setEnabled(hsmwConcreteUser.getEnabled());
		}

		if(AccountTypeEnum.TPSP.getValue().equals(type)){
			HsmwTpspUser hsmwTpspUser = hsmwTpspUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwTpspUser)){
				return  DataResponse.failure(ErrorCodeUtil.E_220,"该供应商账号不存在！");
			}
			loginUser.setId(hsmwTpspUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(hsmwTpspUser.getName());
			loginUser.setEnabled(hsmwTpspUser.getEnabled());
		}
		if(AccountTypeEnum.SALE.getValue().equals(type)){
			HsmwSaleUser hsmwSaleUser = hsmwSaleUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwSaleUser)){
				return  DataResponse.failure(ErrorCodeUtil.E_220,"该销售账号不存在！");
			}
			loginUser.setId(hsmwSaleUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(hsmwSaleUser.getName());
			loginUser.setEnabled(hsmwSaleUser.getEnabled());
		}
		if(AccountTypeEnum.PM.getValue().equals(type)){
			HsmwPmUser hsmwPmUser = hsmwPmUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwPmUser)){
				hsmwPmUser = new HsmwPmUser();
				hsmwPmUser.setFlag(false);
				hsmwPmUser.setUsername(loginRequest.getUsername());
				hsmwPmUser.setType(UserTypeEnum.VISITOR.getValue());
				hsmwPmUser.setEnabled(true);
				hsmwPmUser.setLastLoginTime(LocalDateTime.now());
				hsmwPmUser.setAvatar(currentHsmwUserUtils.getRandomHeadSculpture());
				String userId = CommonUtils.generateId(hsmwPmUser);
				hsmwPmUser.setId(userId);
				hsmwPmUserService.save(hsmwPmUser);
			}
			loginUser.setId(hsmwPmUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(hsmwPmUser.getName());
			loginUser.setEnabled(hsmwPmUser.getEnabled());

			List<HsmwItem> items = hsmwItemService.list(new LambdaQueryWrapper<HsmwItem>()
					.eq(HsmwItem::getCreateUser,hsmwPmUser.getId()));
			if(CollectionUtil.isNotEmpty(items)){
				ifExistsItem="1";
			}
			dataMap.put("ifExistsItem",ifExistsItem);
			dataMap.put("auditStatus",hsmwPmUser.getAuditStatus());
		}
		if(AccountTypeEnum.DRIVER.getValue().equals(type)){
			HsmwDriverUser hsmwDriverUser = hsmwDriverUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwDriverUser)){
				hsmwDriverUser = new HsmwDriverUser();
				hsmwDriverUser.setFlag(false);
				hsmwDriverUser.setUsername(loginRequest.getUsername());
				hsmwDriverUser.setType(UserTypeEnum.VISITOR.getValue());
				hsmwDriverUser.setEnabled(true);
				hsmwDriverUser.setLastLoginTime(LocalDateTime.now());
				String userId = CommonUtils.generateId(hsmwDriverUser);
				hsmwDriverUser.setAvatar(currentHsmwUserUtils.getRandomHeadSculpture());
				hsmwDriverUser.setId(userId);
				hsmwDriverUserService.save(hsmwDriverUser);
			}
			loginUser.setId(hsmwDriverUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(hsmwDriverUser.getName());
			loginUser.setEnabled(hsmwDriverUser.getEnabled());
		}
		if(AccountTypeEnum.HTN.getValue().equals(type)|| UserTypeEnum.SELFRUN.getValue().equals(type) || UserTypeEnum.FOREMAN.getValue().equals(type)){
			HsmwHtnUser hsmwHtnUser = hsmwHtnUserService.findByUsername(username);
			if(StringUtils.isNull(hsmwHtnUser)){
				hsmwHtnUser = new HsmwHtnUser();
				hsmwHtnUser.setFlag(false);
				hsmwHtnUser.setUsername(loginRequest.getUsername());
				hsmwHtnUser.setName(loginRequest.getUsername());
				hsmwHtnUser.setType(HtnUserTypeEnum.NORMAL.getValue());
				hsmwHtnUser.setEnabled(true);
				hsmwHtnUser.setLastLoginTime(LocalDateTime.now());
				String userId = CommonUtils.generateId(hsmwHtnUser);
				hsmwHtnUser.setId(userId);
				hsmwHtnUser.setAvatar(currentHsmwUserUtils.getRandomHeadSculpture());
				hsmwHtnUserService.save(hsmwHtnUser);
			}
			loginUser.setId(hsmwHtnUser.getId());
			loginUser.setType(loginRequest.getType());
			loginUser.setUsername(loginRequest.getUsername());
			loginUser.setName(loginRequest.getUsername());
			loginUser.setEnabled(hsmwHtnUser.getEnabled());
		}

		String token = JwtTokenUtils.createToken(JSONObject.toJSONString(loginUser), loginUser.getId(), new ArrayList<>(), true);
		stringRedisTemplate.opsForValue().set(loginUser.getId(), token, 1000, TimeUnit.DAYS);
		dataMap.put(SecurityConstants.TOKEN_HEADER, token);
		dataMap.put("phone",loginRequest.getUsername());
		return new DataResponse(SUCCESS, dataMap);
	}
}
